package com.yonyou.pmclouds.team.rmiimpl;

import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoUpdateProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.UpdateTsProcessor;
import com.yonyou.pmclouds.basecom.bp.template.SingleDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleInsertBpTemplate;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.exception.ConcurrentOperationException;
import com.yonyou.pmclouds.basecom.lock.AutoReleaseLockUtil;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.team.entity.TeamEnterpriseVO;
import com.yonyou.pmclouds.team.entity.TeamMemberVO;
import com.yonyou.pmclouds.team.mapper.TeamEnterpriseMapper;
import com.yonyou.pmclouds.team.mapper.TeamMapper;
import com.yonyou.pmclouds.team.rmiitf.TeamEnterpriseMaintain;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class TeamMaintainForProject {
    private static final String[] STATE_UPDATE_FIELD = new String[]{CommonFieldConst.CHANGE_FLAG, CommonFieldConst.MODIFIER,
            CommonFieldConst.MODIFYTIME, TeamMemberVO.PROJECT_STATE};
    private static final String[] DELETE_UPDATE_FIELD = new String[]{CommonFieldConst.CHANGE_FLAG, CommonFieldConst.MODIFIER,
            CommonFieldConst.MODIFYTIME,  CommonFieldConst.DR};
    @Autowired
    private TeamMapper mapper;
    @Autowired
    private TeamEnterpriseMapper enterpriseMapper;
    @Autowired
    private TeamEnterpriseMaintain enterpriseMaintain;

    public void updateProjectStateInTeam(ProjectVO projectVO) throws BusinessException {
        // lock project
        if (!AutoReleaseLockUtil.addAutoReleaseLock(projectVO.getPkProject())) {
            throw new ConcurrentOperationException();
        }
        TeamMemberVO[] members = mapper.queryTeamByProject(projectVO.getPkProject());
        UpdateTsProcessor<TeamMemberVO> tsProcessor = new UpdateTsProcessor<>();
        AuditInfoUpdateProcessor<TeamMemberVO> auditProcessor = new AuditInfoUpdateProcessor<>();
        for (TeamMemberVO memberVO : members) {
            memberVO.setProjectState(projectVO.getProjectState());
            tsProcessor.process(memberVO, null);
            auditProcessor.process(memberVO, null);
        }
        for (TeamMemberVO memberVO : members) {
            mapper.updateFields(memberVO, STATE_UPDATE_FIELD);
        }
    }

    public void deleteTeamByProject(String projectid) throws BusinessException {
        // lock project
        if (!AutoReleaseLockUtil.addAutoReleaseLock(projectid)) {
            throw new ConcurrentOperationException();
        }
        TeamMemberVO[] members = mapper.queryTeamByProject(projectid);
        UpdateTsProcessor<TeamMemberVO> tsProcessor = new UpdateTsProcessor<>();
        AuditInfoUpdateProcessor<TeamMemberVO> auditProcessor = new AuditInfoUpdateProcessor<>();
        for (TeamMemberVO memberVO : members) {
            memberVO.setDr((byte)1);
            tsProcessor.process(memberVO, null);
            auditProcessor.process(memberVO, null);
        }
        for (TeamMemberVO memberVO : members) {
            mapper.updateFields(memberVO, DELETE_UPDATE_FIELD);
        }
    }

    public void insertProjectManager(String userid, String enterpriseid, String projectid, Byte state) throws BusinessException {
        // 插入项目经理
        TeamMemberVO member = new TeamMemberVO();
        member.setPkTenant(RuntimeEnvironment.getTenantId());
        member.setPkUser(userid);
        member.setPkProject(projectid);
        member.setUserRole(TeamMemberVO.UserRoleConst.ROLE_OWNER);
        member.setProjectState(state);
        member.setPkEnterprise(enterpriseid);
        SingleInsertBpTemplate<TeamMemberVO> template = new SingleInsertBpTemplate<>(mapper);
        // 设置审计信息
        template.addBeforeProcessor(new AuditInfoInsertProcessor<TeamMemberVO>());
        template.insert(member);
    }

    public void updateProjectManager(String userid, String enterpriseid, String projectid) throws BusinessException {

        TeamMemberVO[] memeberVOs = mapper.queryTeamByProject(projectid);

        String oldEntId = null;

        Map<String,List<TeamMemberVO>> teamMemberVOMap = new HashMap<String,List<TeamMemberVO>>();
        TeamMemberVO manager = null;

        if(ArrayUtils.isEmpty(memeberVOs))
            return;

        //新项目经理为之前项目团队成员时 先执行删除再更新
        TeamMemberVO teamMemberVO = null;
        for(TeamMemberVO member : memeberVOs){
            if(member.getPkUser().equals(userid)){
                teamMemberVO = member;
                break;
            }
        }

        if(teamMemberVO != null){
            SingleDeleteBpTemplate memDelBp =  new SingleDeleteBpTemplate<TeamMemberVO>(mapper);
            memDelBp.addBeforeProcessor(new AuditInfoUpdateProcessor());
            memDelBp.delete(teamMemberVO);
            //将删除的成员从查询结果中移除
            ArrayList<TeamMemberVO> memberList = new ArrayList<TeamMemberVO>(Arrays.asList(memeberVOs));
            memberList.remove(teamMemberVO);
            memeberVOs = memberList.toArray(new TeamMemberVO[0]);
        }

        for (TeamMemberVO memberVO : memeberVOs){
            if(memberVO.getPkUser().equals(userid)){
                // 获取到之前项目经理数据的企业ID
                oldEntId = memberVO.getPkEnterprise();
                memberVO.setPkUser(userid);
                memberVO.setPkEnterprise(enterpriseid);
                manager = memberVO;
            }
            if( teamMemberVOMap.get(memberVO.getPkEnterprise())==null || teamMemberVOMap.get(memberVO.getPkEnterprise()).size() ==0 ){
                teamMemberVOMap.put(memberVO.getPkEnterprise(),new ArrayList<TeamMemberVO>());
            }
            teamMemberVOMap.get(memberVO.getPkEnterprise()).add(memberVO);
        }

        if(!enterpriseid.equals(oldEntId)){
            if(teamMemberVOMap.get(oldEntId) == null || teamMemberVOMap.get(oldEntId).size()==0){
                TeamEnterpriseVO entVO = new TeamEnterpriseVO();
                entVO.setPkEnterprise(oldEntId);

                entVO = enterpriseMapper.queryByProAndEnt(manager.getPkProject(),oldEntId);
                if(entVO != null){
                    SingleDeleteBpTemplate delBp =  new SingleDeleteBpTemplate<TeamEnterpriseVO>(enterpriseMapper);
                    delBp.addBeforeProcessor(new AuditInfoUpdateProcessor());
                    delBp.delete(entVO);
                }

            }
            // 如果更改后的项目经理所属的企业不属于原有团队，则在参与方中新增该企业
            if(teamMemberVOMap.get(enterpriseid).size()== 1){
                TeamEnterpriseVO newEntVO = new TeamEnterpriseVO();
                newEntVO.setPkEnterprise(enterpriseid);
                newEntVO.setPkProject(manager.getPkProject());
                newEntVO.setPkTenant(manager.getPkTenant());
                // 不知道直接设置成业主方会不会有问题
                newEntVO.setEntRole(TeamEnterpriseVO.EnterpriseRoleConst.ROLE_OWNER);

                enterpriseMaintain.addEnterpriseToProject(manager.getPkProject(),new TeamEnterpriseVO[]{newEntVO});
            }
        }

        mapper.updateFields(manager, new String[]{TeamMemberVO.PK_USER, TeamMemberVO.PK_ENTERPRISE});
    }

}
